package com.wwg.springboard;

import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.wwg.springboard.shortcut.Shortcut;
import com.wwg.springboard.shortcut.ShortcutUtils;
import com.wwg.widget.ViewType;
import com.wwg.widget.impl.SpringBoardContentView;
import com.wwg.widget.impl.SpringBoardView;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class SpringBoardMediator {
    private static final String TAG = "SpringBoardMediator";

    private final FolderAdapter mFolderAdapter;

    public SpringBoardMediator(SpringBoardView view) {
        List<Shortcut> subscribe = ShortcutUtils.getSubscribe();

        List<Pair<Shortcut, List<Shortcut>>> content = new LinkedList<>();
        for (Shortcut shortcut: subscribe) {
            content.add(new Pair<>(shortcut, new ArrayList<>()));
        }

        ContentAdapter contentAdapter = new ContentAdapter();
        contentAdapter.setData(content);

        mFolderAdapter = new FolderAdapter();
        view.setAdapter(contentAdapter, mFolderAdapter);
    }

    private class ContentAdapter extends SpringBoardView.Adapter<Holder> {
        List<Pair<Shortcut, List<Shortcut>>> data = new ArrayList<>();

        public void setData(List<Pair<Shortcut, List<Shortcut>>> data) {
            this.data.addAll(data);
        }

        @Override
        protected boolean onOrderChanged(int one, int another) {
            Pair<Shortcut, List<Shortcut>> removed = data.remove(another);
            data.add(one, removed);

            // Log.i(TAG, "one " + one + " another " + another + " " + removed);
            return true;
        }

        @Override
        protected boolean onItemRemoved(int position) {
            if (isIndexInvalid(position)) {
                return false;
            }

            Pair<Shortcut, List<Shortcut>> it = data.get(position);
            UserActionHistoryProxy.getInstance().delete("content", it.first.name, position);
            data.remove(position);
            return true;
        }

        @Override
        protected boolean onItemInserted(Object insert) {
            int index = data.size();
            if (insert instanceof Shortcut) {
                Shortcut shortcut = (Shortcut) insert;
                data.add(new Pair<>(shortcut, new ArrayList<>()));
                UserActionHistoryProxy.getInstance().insert("content", shortcut.name, index);
            } else {
                Pair<Shortcut, List<Shortcut>> it = (Pair<Shortcut, List<Shortcut>>) insert;
                data.add(it);
                UserActionHistoryProxy.getInstance().insert("content", it.first.name, index);
            }

            return true;
        }

        @Override
        protected int checkAndRemoveFolder() {
            Pair<Shortcut, List<Shortcut>> folder = mFolderAdapter.data;
            if (folder != null && folder.second.size() <= 0) {
                mFolderAdapter.setData(null);
                return data.indexOf(folder);
            }

            return -1;
        }

        @Override
        protected void onItemHoverChanged(SpringBoardContentView.ViewHolder holder, boolean hovered) {
            if (holder instanceof Holder) {
                ((Holder) holder).hovered.setVisibility(hovered ? View.VISIBLE : View.INVISIBLE);
            }
        }

        @Override
        protected boolean canMakeFolder(int position, boolean target) {
            if (isIndexInvalid(position)) {
                return false;
            }

            Pair<Shortcut, List<Shortcut>> current = data.get(position);
            if (current.second.size() > 0) {
                return true;
            }

            for (Pair<Shortcut, List<Shortcut>> item : data) {
                if (item.second.size() > 0) {
                    return false;
                }
            }

            return true;
        }

        @Override
        protected void onMakeFolder(int origin, int sojourner) {
            Pair<Shortcut, List<Shortcut>> removed = data.get(sojourner);
            Pair<Shortcut, List<Shortcut>> originPair = data.get(origin);
            originPair.second.add(originPair.first);
            originPair.second.add(removed.first);

            data.remove(sojourner);
            mFolderAdapter.setData(originPair);
        }

        @Override
        public int getItemCount() {
            return data.size();
        }

        @Override
        public Object getItem(int index) {
            return data.get(index);
        }

        @Override
        public int getItemViewType(int position) {
            Pair<Shortcut, List<Shortcut>> folder = mFolderAdapter.data;
            if (folder != null && data.indexOf(folder) == position) {
                return ViewType.FOLDER;
            } else {
                return ViewType.NORMAL;
            }
        }

        @NonNull
        @Override
        protected Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            switch (viewType) {
                case ViewType.FOLDER:
                    return new FolderHolder(
                            inflater.inflate(
                                    R.layout.cqttech_spring_subscribed_folder,
                                    parent, false
                            ));

                case ViewType.NORMAL:
                    return new SpringHolder(
                            inflater.inflate(
                                    R.layout.cqttech_spring_subscribed_shortcut_content,
                                    parent, false
                            )
                    );
                default:
                    throw new IllegalArgumentException("unknown view type!");
            }
        }

        @Override
        protected void onRecycleViewHolder(SpringBoardContentView.ViewHolder holder) {
            super.onRecycleViewHolder(holder);
            if (holder instanceof Holder) {
                ((Holder) holder).hovered.setVisibility(View.INVISIBLE);
            }
        }

        @Override
        protected void onBindViewHolder(@NonNull Holder holder, int position) {
            Pair<Shortcut, List<Shortcut>> item = data.get(position);
            if (holder instanceof FolderHolder) {
                List<Pair<Integer, String>> folders = new ArrayList<>();
                Pair<Shortcut, List<Shortcut>> origin = mFolderAdapter.data;
                if (origin != null) {
                    List<Shortcut> second = origin.second;
                    for (Shortcut shortcut: second) {
                        folders.add(new Pair<>(shortcut.iconRes, shortcut.iconUrl));
                    }
                }
                ((FolderHolder) holder).folderView.setData(folders);
            } else if (holder instanceof SpringHolder) {
                SpringHolder springHolder = (SpringHolder) holder;
                Shortcut shortcut = item.first;
                springHolder.logo.setImageResource(shortcut.iconRes);
                springHolder.title.setText(shortcut.name);
                if (TextUtils.isEmpty(shortcut.name)) {
                    springHolder.delete.setVisibility(View.GONE);
                } else {
                    springHolder.delete.setVisibility(View.VISIBLE);
                }

//                springHolder.delete.setOnClickListener(v -> {
//                    if (notifyItemRemoved(holder)) {
//                        data.remove(holder.index);
//                    }
//                });
            }
        }

        private boolean isIndexInvalid(int index) {
            return index < 0 || index >= data.size();
        }

        class FolderHolder extends Holder {
            final FolderView folderView;

            public FolderHolder(@NonNull View view) {
                super(view);
                folderView = (FolderView) view;
            }
        }
    }

    private static class FolderAdapter extends SpringBoardView.Adapter<Holder> {
        private Pair<Shortcut, List<Shortcut>> data;

        public void setData(Pair<Shortcut, List<Shortcut>> in) {
            data = in;
        }

        @Override
        protected boolean onOrderChanged(int one, int another) {
            if (data == null) {
                return false;
            }

            List<Shortcut> list = data.second;
            Shortcut removed = list.remove(another);
            list.add(one, removed);

            Log.i(TAG, "one " + one + " another " + another + " " + removed);
            return true;
        }

        @Override
        protected boolean onItemRemoved(int position) {
            if (isIndexInvalid(position)) {
                return false;
            }

            if (data == null) {
                return false;
            }

            List<Shortcut> list = data.second;
            Shortcut it = list.get(position);
            UserActionHistoryProxy.getInstance().delete("folder", it.name, position);
            list.remove(position);
            return true;
        }

        @Override
        protected boolean onItemInserted(Object insert) {
            if (data == null) {
                return false;
            }

            List<Shortcut> list = data.second;

            int index = list.size();
            if (insert instanceof Shortcut) {
                Shortcut it = (Shortcut) insert;
                list.add(it);
                UserActionHistoryProxy.getInstance().insert("folder", it.name, index);
            } else if (insert instanceof Pair && ((Pair<?, ?>) insert).first instanceof Shortcut) {
                Shortcut it = (Shortcut) ((Pair<?, ?>) insert).first;
                list.add(it);
                UserActionHistoryProxy.getInstance().insert("folder", it.name, index);
            } else {
                return false;
            }

            return true;
        }

        @Override
        protected void onItemHoverChanged(SpringBoardContentView.ViewHolder holder, boolean hovered) {
            if (holder instanceof Holder) {
                ((Holder) holder).hovered.setVisibility(hovered ? View.VISIBLE : View.INVISIBLE);
            }
        }

        @Override
        protected boolean canMakeFolder(int position, boolean b) {
            return false;
        }

        @Override
        protected void onMakeFolder(int origin, int sojourner) {
            // do nothing
        }

        @Override
        public int getItemCount() {
            if (data == null) {
                return 0;
            }

            List<Shortcut> list = data.second;
            return list.size();
        }

        @Override
        public Object getItem(int index) {
            if (data == null) {
                return 0;
            }

            List<Shortcut> list = data.second;
            return list.get(index);
        }

        @Override
        public int getItemViewType(int position) {
            return ViewType.NORMAL;
        }

        @NonNull
        @Override
        protected Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            if (viewType == ViewType.NORMAL) {
                return new SpringHolder(
                        inflater.inflate(
                                R.layout.cqttech_spring_subscribed_shortcut_folder,
                                parent, false
                        )
                );
            }
            throw new IllegalArgumentException("unknown view type!");
        }

        @Override
        protected void onRecycleViewHolder(SpringBoardContentView.ViewHolder holder) {
            super.onRecycleViewHolder(holder);
            if (holder instanceof Holder) {
                ((Holder) holder).hovered.setVisibility(View.INVISIBLE);
            }
        }

        @Override
        protected void onBindViewHolder(@NonNull Holder holder, int position) {
            if (data == null) {
                return;
            }

            List<Shortcut> list = data.second;
            Shortcut shortcut = list.get(position);
            if (holder instanceof SpringHolder) {
                SpringHolder springHolder = (SpringHolder) holder;
                springHolder.logo.setImageResource(shortcut.iconRes);
                springHolder.title.setText(shortcut.name);
                if (TextUtils.isEmpty(shortcut.name)) {
                    springHolder.delete.setVisibility(View.GONE);
                } else {
                    springHolder.delete.setVisibility(View.VISIBLE);
                }

//                springHolder.delete.setOnClickListener(v -> {
//                    if (notifyItemRemoved(holder)) {
//                        data.remove(holder.index);
//                    }
//                });
            }
        }

        private boolean isIndexInvalid(int index) {
            if (data == null) {
                return true;
            }

            List<Shortcut> list = data.second;
            return index < 0 || index >= list.size();
        }
    }

    static class Holder extends SpringBoardView.ViewHolder {
        final View hovered;

        public Holder(@NonNull View view) {
            super(view);
            hovered = itemView.findViewById(R.id.hovered_background);
        }
    }

    static class SpringHolder extends Holder {
        final ImageView logo;
        final TextView title;
        final ImageView delete;

        public SpringHolder(@NonNull View view) {
            super(view);

            logo = itemView.findViewById(R.id.iv_logo);
            title = itemView.findViewById(R.id.tv_title);
            delete = itemView.findViewById(R.id.nav_delete);
        }

        @Override
        @NonNull
        public String toString() {
            return "SpringHolder{" +
                    ", title=" + title.getText() +
                    ", type=" + type +
                    ", index=" + index +
                    '}';
        }
    }
}
